package top.mschen.blog.common.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import top.mschen.blog.common.annotation.TargetDataSource;
import top.mschen.blog.common.config.DynamicDataSourceContextHolder;

/**
 * 测试  回滚 12111
 */
@Aspect
@Order(0)//保证该AOP在@Transactional之前执行，不然切换数据源无效
@Component
public class DynamicDataSourceAspect2 {

    private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSourceAspect2.class);
       /*
     * @Before("@annotation(ds)")
     * 的意思是：
     *
     * @Before：在方法执行之前进行执行：
     * @annotation(targetDataSource)：
     *会拦截注解targetDataSource的方法，否则不拦截;
     */

    @Before("@annotation(targetDataSource)")
    public void changeDataSource(JoinPoint point, TargetDataSource targetDataSource) throws Throwable {

        //获取当前的指定的数据源;
        String dsId = targetDataSource.value();
        //如果不在我们注入的所有的数据源范围之内，那么输出警告信息，系统自动使用默认的数据源。
        if (!DynamicDataSourceContextHolder.containDataSourceKey(dsId)) {
            System.err.println("数据源[{}]不存在，使用默认数据源 > {}"+targetDataSource.value()+point.getSignature());
        } else {
            System.out.println("Use DataSource : {} > {}"+targetDataSource.value()+point.getSignature());
            //找到的话，那么设置到动态数据源上下文中。
            DynamicDataSourceContextHolder.setDataSourceKey(targetDataSource.value());
        }
    }



    @After("@annotation(targetDataSource)")
    public void restoreDataSource(JoinPoint point, TargetDataSource targetDataSource) {
        System.out.println("Revert DataSource : {} > {}"+targetDataSource.value()+point.getSignature());
        //方法执行完毕之后，销毁当前数据源信息，进行垃圾回收。
        DynamicDataSourceContextHolder.clearDataSourceKey();

    }
}
